#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

#define BUFFER_SIZE 5  // 缓冲区容量
#define NUM_ITEMS 10   // 生产者生成的总数据量

int buffer[BUFFER_SIZE];  // 缓冲区数组
int in = 0;               // 生产者写入位置
int out = 0;              // 消费者读取位置

sem_t empty;              // 空槽信号量（初始值为BUFFER_SIZE）
sem_t full;               // 满槽信号量（初始值为0）
pthread_mutex_t mutex;    // 互斥锁，保护缓冲区的访问

// 生产者线程函数
void *producer(void *arg) {
    for (int i = 0; i < NUM_ITEMS; i++) {
        sem_wait(&empty);          // 等待空槽
        pthread_mutex_lock(&mutex); // 加锁

        // 生产数据并放入缓冲区
        buffer[in] = i;
        printf("生产者写入: %d\n", buffer[in]);
        in = (in + 1) % BUFFER_SIZE;

        pthread_mutex_unlock(&mutex); // 解锁
        sem_post(&full);             // 增加满槽
    }
    return NULL;
}

// 消费者线程函数
void *consumer(void *arg) {
    for (int i = 0; i < NUM_ITEMS; i++) {
        sem_wait(&full);            // 等待满槽
        pthread_mutex_lock(&mutex); // 加锁

        // 从缓冲区取出数据并消费
        int item = buffer[out];
        printf("消费者读取: %d\n", item);
        out = (out + 1) % BUFFER_SIZE;

        pthread_mutex_unlock(&mutex); // 解锁
        sem_post(&empty);            // 增加空槽
    }
    return NULL;
}

int main() {
    pthread_t prod_tid, cons_tid;

    // 初始化信号量和互斥锁
    sem_init(&empty, 0, BUFFER_SIZE); // 初始空槽数=缓冲区容量
    sem_init(&full, 0, 0);           // 初始满槽数=0
    pthread_mutex_init(&mutex, NULL);

    // 创建生产者和消费者线程
    pthread_create(&prod_tid, NULL, producer, NULL);
    pthread_create(&cons_tid, NULL, consumer, NULL);

    // 等待线程结束
    pthread_join(prod_tid, NULL);
    pthread_join(cons_tid, NULL);

    // 销毁信号量和互斥锁
    sem_destroy(&empty);
    sem_destroy(&full);
    pthread_mutex_destroy(&mutex);

    return 0;
}
